﻿#include "centerCombobox.h"
#include <QApplication>

centerCombobox::centerCombobox(QWidget *parent) : QComboBox(parent)
{
    this->setStyle(QStyleFactory::create("windowsvista"));
    if(lineEdit == 0)
    {
        lineEdit = new QLineEdit(this);
        lineEdit->setObjectName("lintEditAdptive");
        lineEdit->setReadOnly(true);
        lineEdit->setAlignment(Qt::AlignCenter);
        lineEdit->setFocusPolicy(Qt::NoFocus);
        connect(lineEdit,&QLineEdit::selectionChanged,[=]{
            lineEdit->deselect();
        });
        connect(this,&QComboBox::currentTextChanged,[=](const QString &text){
            for(int i = 0; i < this->count(); i++)
            {
                if(this->itemText(i) == text)
                {
                    this->setCurrentIndex(i);
                    emit signalIndexChanged(this->itemText(i));
                    break;
                }
            }
        });
    }
    this->setLineEdit(lineEdit);
    lineEdit->installEventFilter(this);
    this->installEventFilter(this);
    timer=QDateTime::currentDateTime();

    int h = this->height();
    this->styleSheet().clear();
    QString sheet = QString("QComboBox{\
                            background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(250, 250, 250, 255), stop:0.5 rgba(240, 240, 240, 255), stop:1 rgba(230, 230, 230, 255));\
                            border: 1px solid rgb(200, 200, 200);\
                            border-radius: 6px;\
                            padding-left:20px;\
                            }QComboBox::drop-down {width:40px;border-image: url(:/image/icons/downarrow.png);\
                            }QComboBox QAbstractItemView {background-color:rgba(250, 250, 250, 255);\
                            }QComboBox QAbstractItemView::item {height:%1px;\
                            }QComboBox QScrollBar::add-line:vertical {border:none;\
                            }").arg(h);

    this->setStyleSheet(sheet);
    listView = new QListView;
    this->setView(listView);
    this->view()->setStyleSheet("QListView QScrollBar:sub-line:vertical { display: none; }");

    if (pScroller)
    {
        return;
    }
    pScroller = QScroller::scroller(qobject_cast<QListView*>(this->view()));
    connect(pScroller, &QScroller::stateChanged, this, [=](const QScroller::State &newState)
        {
            if (QScroller::activeScrollers().count() > 2)
            {
                QList<QScroller *> scrollers = QScroller::activeScrollers();
                foreach(auto bean, scrollers)
                {
                    //qDebug() << "more :" << bean->state();
                    bean->stop();
                }
            }

            //能产生两个事件绝对是要停止滚动的，这样才能保证退出再进入不会崩溃
            if (newState == QScroller::Pressed || newState == QScroller::Inactive)
            {
                QList<QScroller *> scrollers = QScroller::activeScrollers();
                foreach(auto bean, scrollers)
                {
                    bean->stop();
                }
            }
        });

    pScroller->grabGesture(qobject_cast<QListView*>(this->view())->viewport(),QScroller::LeftMouseButtonGesture);
    this->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}

centerCombobox::~centerCombobox()
{
    if (nullptr != listView)
    {
        delete listView;
        listView = nullptr;
    }
}

//添加单个子项
void centerCombobox::addItem(const QString &text)
{
    QComboBox::addItem(text);
    showP = false;
    initSheet();
}

void centerCombobox::addItem(const QString &atext, const QVariant &auserData)
{
    QComboBox::addItem(atext,auserData);
    showP = false;
    initSheet();
}

//添加多个子项
void centerCombobox::addItems(const QStringList &texts)
{
    QComboBox::addItems(texts);
    showP = false;
    initSheet();
}

//插入单个子项
void centerCombobox::instertItem(int aindex, const QString &atext)
{
    QComboBox::insertItem(aindex,atext);
    showP = false;
    initSheet();
}

//插入多个子项
void centerCombobox::instertItems(int aindex, const QStringList &atexts)
{
    QComboBox::insertItems(aindex,atexts);
    showP = false;
    initSheet();
}

//事件过滤处理
bool centerCombobox::eventFilter(QObject *target, QEvent *event)
{
    if (target == this)
    {
        if (event->type() == QEvent::FocusIn)
        {
            if(showP)
                    timer=QDateTime::currentDateTime();   //用于判断收起还是显示
        }
        else if (event->type() == QEvent::FocusOut)
        {
            timer=QDateTime::currentDateTime();
        }
        else  if (event->type() == QEvent::MouseButtonPress
                 || event->type() == QEvent::MouseButtonDblClick
                 || event->type() == QEvent::TouchBegin)
        {
            int msecs = timer.msecsTo(QDateTime::currentDateTime());
            QSize sz =  this->geometry().size()-=QSize(5,5);
            QPoint pt(sz.width(),sz.height());
            if(msecs > 50)
            {
                bool bPress = true;
                if(event->type() == QEvent::MouseButtonPress)
                {
                    QMouseEvent * pEvt = (QMouseEvent * )(event);
                    if(pEvt&& pEvt->pos() == pt)
                    {
                        bPress = false;
                    }
                }
                if(bPress)
                {
                    timer=QDateTime::currentDateTime();
                    QMouseEvent evt(QEvent::MouseButtonPress,pt,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
                    qApp->sendEvent(this,&evt);
                    return true;
                }
            }
            else
            {
                if(event->type() == QEvent::MouseButtonPress)
                {
                    QMouseEvent * pEvt = (QMouseEvent * )(event);
                    if(pEvt&& pEvt->pos() != pt)
                    {
                        return true;
                    }
                    else
                    {
                        return QWidget::eventFilter(target, event);
                    }
                }
            }
        }
    }
    else if (target == lineEdit)
    {
        if(event->type() == QEvent::KeyPress)
        {
            return true;
        }
        if (event->type() == QEvent::MouseButtonPress
            || event->type() == QEvent::MouseButtonDblClick
            || event->type() == QEvent::TouchBegin)
        {
            if(this->isEnabled())
            {
                this->setFocus();
                int msecs = timer.msecsTo(QDateTime::currentDateTime());
                if(msecs > 50)
                {
                    //发送鼠标左键事件，坐标在向下箭头的位置
                    QSize sz =  this->geometry().size()-=QSize(5,5);
                    QPoint pt(sz.width(),sz.height());
                    QMouseEvent evt(QEvent::MouseButtonPress,pt,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
                    qApp->sendEvent( this,&evt);
                }
            }
            return true;
        }
    }
    return QComboBox::eventFilter(target, event);
}

//显示下拉项
void centerCombobox::showPopup()
{
    if(!showP)
    {
        showP = true;
    }
    timer=QDateTime::currentDateTime();
    QListView *listView = static_cast<QListView *>(this->view());
    if (listView) {
        listView->move(0, 0);
    }
    QComboBox::showPopup();
}

//隐藏下拉项
void centerCombobox::hidePopup()
{
    if(showP)
    {
        showP = false;
    }
    timer=QDateTime::currentDateTime();
    QComboBox::hidePopup();
}

//设置字体
void centerCombobox::setFont(const QFont &font)
{
    QComboBox::setFont(font);
    lineEdit->setFont(font);
    for(auto w:this->findChildren<QWidget*>())
    {
        w->setFont(font);
    }
    initSheet();
}

//初始化风格
void centerCombobox::initSheet()
{
    int row = this->currentIndex();

    this->view()->setFrameShape(QFrame::NoFrame);

    this->view()->setStyleSheet(
    "QListView {"
        "padding-top: 2px;" /* 上边距 */
        "padding-bottom: 2px;" /* 下边距 */
        "padding-left: 2px;" /* 左边距 */
        "padding-right: 2px;" /* 右边距 */
    "}"
     "QListView::item{\
     height:60px}"
     "QListView QScrollBar::add-line:vertical {background:none;height:0;border:none;display:none}");
    this->view()->update();
    //下拉列表居中
    model =  static_cast<QStandardItemModel*>(this->view()->model());
    if(model)
    {
        for(int i = 0; i < model->rowCount(); i ++)
        {
            if(model->item(i))
            {
                model->item(i)->setTextAlignment(Qt::AlignCenter);
                model->item(i)->setFont(this->font());
            }
        }
    }
    if(row >= 0)
        this->setCurrentIndex(row);
}
